/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
 
This file is part of Quake III Arena source code.
 
Quake III Arena source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
 
Quake III Arena source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
===========================================================================
*/
//
#include "ui_local.h"

#define MODEL_BACK0			"menu/art/back_0"
#define MODEL_BACK1			"menu/art/back_1"
#define MODEL_SELECT		"menu/art/opponents_select"
#define MODEL_SELECTED		"menu/art/opponents_selected"
#define MODEL_FRAMEL		"menu/art/frame1_l"
#define MODEL_FRAMER		"menu/art/frame1_r"
#define MODEL_PORTS			"menu/art/player_models_ports"
#define MODEL_ARROWS		"menu/art/gs_arrows_0"
#define MODEL_ARROWSL		"menu/art/gs_arrows_l"
#define MODEL_ARROWSR		"menu/art/gs_arrows_r"

#define LOW_MEMORY			(5 * 1024 * 1024)

static char* playermodel_artlist[] =
    {
        MODEL_BACK0,
        MODEL_BACK1,
        MODEL_SELECT,
        MODEL_SELECTED,
        MODEL_FRAMEL,
        MODEL_FRAMER,
        MODEL_PORTS,
        MODEL_ARROWS,
        MODEL_ARROWSL,
        MODEL_ARROWSR,
        NULL
    };

#define PLAYERGRID_COLS		4
#define PLAYERGRID_ROWS		4
#define MAX_MODELSPERPAGE	(PLAYERGRID_ROWS*PLAYERGRID_COLS)

#define MAX_PLAYERMODELS	256

#define ID_PLAYERPIC0		0
#define ID_PLAYERPIC1		1
#define ID_PLAYERPIC2		2
#define ID_PLAYERPIC3		3
#define ID_PLAYERPIC4		4
#define ID_PLAYERPIC5		5
#define ID_PLAYERPIC6		6
#define ID_PLAYERPIC7		7
#define ID_PLAYERPIC8		8
#define ID_PLAYERPIC9		9
#define ID_PLAYERPIC10		10
#define ID_PLAYERPIC11		11
#define ID_PLAYERPIC12		12
#define ID_PLAYERPIC13		13
#define ID_PLAYERPIC14		14
#define ID_PLAYERPIC15		15
#define ID_PREVPAGE			100
#define ID_NEXTPAGE			101
#define ID_BACK				102

typedef struct
{
    menuframework_s	menu;
    menubitmap_s	pics[MAX_MODELSPERPAGE];
    menubitmap_s	picbuttons[MAX_MODELSPERPAGE];
    menubitmap_s	framel;
    menubitmap_s	framer;
    menubitmap_s	ports;
    menutext_s		banner;
    menubitmap_s	back;
    menubitmap_s	player;
    menubitmap_s	arrows;
    menubitmap_s	left;
    menubitmap_s	right;
    menutext_s		modelname;
    menutext_s		skinname;
    menutext_s		playername;
    playerInfo_t	playerinfo;
    int				nummodels;
    char			modelnames[MAX_PLAYERMODELS][128];
    int				modelpage;
    int				numpages;
    char			modelskin[64];
    int				selectedmodel;
}
playermodel_t;

static playermodel_t s_playermodel;

/*
=================
PlayerModel_UpdateGrid
=================
*/
static void PlayerModel_UpdateGrid( void )
{
    int	i;
    int	j;

    j = s_playermodel.modelpage * MAX_MODELSPERPAGE;
    for (i=0; i<PLAYERGRID_ROWS*PLAYERGRID_COLS; i++,j++)
    {
        if (j < s_playermodel.nummodels)
        {
            // model/skin portrait
            s_playermodel.pics[i].generic.name         = s_playermodel.modelnames[j];
            s_playermodel.picbuttons[i].generic.flags &= ~QMF_INACTIVE;
        }
        else
        {
            // dead slot
            s_playermodel.pics[i].generic.name         = NULL;
            s_playermodel.picbuttons[i].generic.flags |= QMF_INACTIVE;
        }

        s_playermodel.pics[i].generic.flags       &= ~QMF_HIGHLIGHT;
        s_playermodel.pics[i].shader               = 0;
        s_playermodel.picbuttons[i].generic.flags |= QMF_PULSEIFFOCUS;
    }

    if (s_playermodel.selectedmodel/MAX_MODELSPERPAGE == s_playermodel.modelpage)
    {
        // set selected model
        i = s_playermodel.selectedmodel % MAX_MODELSPERPAGE;

        s_playermodel.pics[i].generic.flags       |= QMF_HIGHLIGHT;
        s_playermodel.picbuttons[i].generic.flags &= ~QMF_PULSEIFFOCUS;
    }

    if (s_playermodel.numpages > 1)
    {
        if (s_playermodel.modelpage > 0)
            s_playermodel.left.generic.flags &= ~QMF_INACTIVE;
        else
            s_playermodel.left.generic.flags |= QMF_INACTIVE;

        if (s_playermodel.modelpage < s_playermodel.numpages-1)
            s_playermodel.right.generic.flags &= ~QMF_INACTIVE;
        else
            s_playermodel.right.generic.flags |= QMF_INACTIVE;
    }
    else
    {
        // hide left/right markers
        s_playermodel.left.generic.flags |= QMF_INACTIVE;
        s_playermodel.right.generic.flags |= QMF_INACTIVE;
    }
}

/*
=================
PlayerModel_UpdateModel
=================
*/
static void PlayerModel_UpdateModel( void )
{
    vec3_t	viewangles;
    vec3_t	moveangles;

    memset( &s_playermodel.playerinfo, 0, sizeof(playerInfo_t) );

    viewangles[YAW]   = 180 - 30;
    viewangles[PITCH] = 0;
    viewangles[ROLL]  = 0;
    VectorClear( moveangles );

    UI_PlayerInfo_SetModel( &s_playermodel.playerinfo, s_playermodel.modelskin );
//    UI_PlayerInfo_SetInfo( &s_playermodel.playerinfo, LEGS_IDLE, TORSO_STAND, viewangles, moveangles, WP_MACHINEGUN, qfalse );
}

/*
=================
PlayerModel_SaveChanges
=================
*/
static void PlayerModel_SaveChanges( void )
{
    Cvar_Set( "model", s_playermodel.modelskin );
    Cvar_Set( "headmodel", s_playermodel.modelskin );
    Cvar_Set( "team_model", s_playermodel.modelskin );
    Cvar_Set( "team_headmodel", s_playermodel.modelskin );
}

/*
=================
PlayerModel_MenuEvent
=================
*/
static void PlayerModel_MenuEvent( void* ptr, int event )
{
    if (event != QM_ACTIVATED)
        return;

    switch (((menucommon_s*)ptr)->id)
    {
    case ID_PREVPAGE:
        if (s_playermodel.modelpage > 0)
        {
            s_playermodel.modelpage--;
            PlayerModel_UpdateGrid();
        }
        break;

    case ID_NEXTPAGE:
        if (s_playermodel.modelpage < s_playermodel.numpages-1)
        {
            s_playermodel.modelpage++;
            PlayerModel_UpdateGrid();
        }
        break;

    case ID_BACK:
        PlayerModel_SaveChanges();
        UI_PopMenu();
        break;
    }
}

/*
=================
PlayerModel_MenuKey
=================
*/
static sfxHandle_t PlayerModel_MenuKey( int key )
{
    menucommon_s*	m;
    int				picnum;

    switch (key)
    {
    case K_KP_LEFTARROW:
    case K_LEFTARROW:
        m = (menucommon_s *)Menu_ItemAtCursor(&s_playermodel.menu);
        picnum = m->id - ID_PLAYERPIC0;
        if (picnum >= 0 && picnum <= 15)
        {
            if (picnum > 0)
            {
                Menu_SetCursor(&s_playermodel.menu,s_playermodel.menu.cursor-1);
                return (menu_move_sound);

            }
            else if (s_playermodel.modelpage > 0)
            {
                s_playermodel.modelpage--;
                Menu_SetCursor(&s_playermodel.menu,s_playermodel.menu.cursor+15);
                PlayerModel_UpdateGrid();
                return (menu_move_sound);
            }
            else
                return (menu_buzz_sound);
        }
        break;

    case K_KP_RIGHTARROW:
    case K_RIGHTARROW:
        m = (menucommon_s *)Menu_ItemAtCursor(&s_playermodel.menu);
        picnum = m->id - ID_PLAYERPIC0;
        if (picnum >= 0 && picnum <= 15)
        {
            if ((picnum < 15) && (s_playermodel.modelpage*MAX_MODELSPERPAGE + picnum+1 < s_playermodel.nummodels))
            {
                Menu_SetCursor(&s_playermodel.menu,s_playermodel.menu.cursor+1);
                return (menu_move_sound);
            }
            else if ((picnum == 15) && (s_playermodel.modelpage < s_playermodel.numpages-1))
            {
                s_playermodel.modelpage++;
                Menu_SetCursor(&s_playermodel.menu,s_playermodel.menu.cursor-15);
                PlayerModel_UpdateGrid();
                return (menu_move_sound);
            }
            else
                return (menu_buzz_sound);
        }
        break;

    case K_MOUSE2:
    case K_ESCAPE:
        PlayerModel_SaveChanges();
        break;
    }

    return ( Menu_DefaultKey( &s_playermodel.menu, key ) );
}

/*
=================
PlayerModel_PicEvent
=================
*/
static void PlayerModel_PicEvent( void* ptr, int event )
{
    int				modelnum;
    int				maxlen;
    char*			buffptr;
    char*			pdest;
    int				i;

    if (event != QM_ACTIVATED)
        return;

    for (i=0; i<PLAYERGRID_ROWS*PLAYERGRID_COLS; i++)
    {
        // reset
        s_playermodel.pics[i].generic.flags       &= ~QMF_HIGHLIGHT;
        s_playermodel.picbuttons[i].generic.flags |= QMF_PULSEIFFOCUS;
    }

    // set selected
    i = ((menucommon_s*)ptr)->id - ID_PLAYERPIC0;
    s_playermodel.pics[i].generic.flags       |= QMF_HIGHLIGHT;
    s_playermodel.picbuttons[i].generic.flags &= ~QMF_PULSEIFFOCUS;

    // get model and strip icon_
    modelnum = s_playermodel.modelpage*MAX_MODELSPERPAGE + i;
    buffptr  = s_playermodel.modelnames[modelnum] + strlen("models/players/");
    pdest    = strstr(buffptr,"icon_");
    if (pdest)
    {
        // track the whole model/skin name
        Q_strncpyz(s_playermodel.modelskin,buffptr,pdest-buffptr+1);
        strcat(s_playermodel.modelskin,pdest + 5);

        // seperate the model name
        maxlen = pdest-buffptr;
        if (maxlen > 16)
            maxlen = 16;
        Q_strncpyz( s_playermodel.modelname.string, buffptr, maxlen );
        Q_strupr( s_playermodel.modelname.string );

        // seperate the skin name
        maxlen = strlen(pdest+5)+1;
        if (maxlen > 16)
            maxlen = 16;
        Q_strncpyz( s_playermodel.skinname.string, pdest+5, maxlen );
        Q_strupr( s_playermodel.skinname.string );

        s_playermodel.selectedmodel = modelnum;

        if( Hunk_MemoryRemaining() > LOW_MEMORY )
        {
            PlayerModel_UpdateModel();
        }
    }
}

/*
=================
PlayerModel_DrawPlayer
=================
*/
static void PlayerModel_DrawPlayer( void *self )
{
    menubitmap_s*	b;

    b = (menubitmap_s*) self;

    if( Hunk_MemoryRemaining() <= LOW_MEMORY )
    {
        UI_DrawProportionalString( b->generic.x, b->generic.y + b->height / 2, "LOW MEMORY", UI_LEFT, color_red );
        return;
    }

    UI_DrawPlayer( b->generic.x, b->generic.y, b->width, b->height, &s_playermodel.playerinfo, uis.realtime/2 );
}

/*
=================
PlayerModel_BuildList
=================
*/
static void PlayerModel_BuildList( void )
{
    int		numdirs;
    int		numfiles;
    char	dirlist[2048];
    char	filelist[2048];
    char	skinname[64];
    char*	dirptr;
    char*	fileptr;
    int		i;
    int		j;
    int		dirlen;
    int		filelen;
    qboolean precache;

    precache = Cvar_VariableValue("com_buildscript");

    s_playermodel.modelpage = 0;
    s_playermodel.nummodels = 0;

    // iterate directory of all player models
    numdirs = FS_GetFileList("models/players", "/", dirlist, 2048 );
    dirptr  = dirlist;
    for (i=0; i<numdirs && s_playermodel.nummodels < MAX_PLAYERMODELS; i++,dirptr+=dirlen+1)
    {
        dirlen = strlen(dirptr);

        if (dirlen && dirptr[dirlen-1]=='/') dirptr[dirlen-1]='\0';

        if (!strcmp(dirptr,".") || !strcmp(dirptr,".."))
            continue;

        // iterate all skin files in directory
        numfiles = FS_GetFileList( va("models/players/%s",dirptr), "tga", filelist, 2048 );
        fileptr  = filelist;
        for (j=0; j<numfiles && s_playermodel.nummodels < MAX_PLAYERMODELS;j++,fileptr+=filelen+1)
        {
            filelen = strlen(fileptr);

            COM_StripExtension(fileptr,skinname);

            // look for icon_????
            if (!Q_stricmpn(skinname,"icon_",5))
            {
                Com_sprintf( s_playermodel.modelnames[s_playermodel.nummodels++],
                             sizeof( s_playermodel.modelnames[s_playermodel.nummodels] ),
                             "models/players/%s/%s", dirptr, skinname );
                //if (s_playermodel.nummodels >= MAX_PLAYERMODELS)
                //	return;
            }

            if( precache )
            {
                S_RegisterSound( va( "sound/player/announce/%s_wins.wav", skinname), qfalse );
            }
        }
    }

    //APSFIXME - Degenerate no models case

    s_playermodel.numpages = s_playermodel.nummodels/MAX_MODELSPERPAGE;
    if (s_playermodel.nummodels % MAX_MODELSPERPAGE)
        s_playermodel.numpages++;
}

/*
=================
PlayerModel_SetMenuItems
=================
*/
static void PlayerModel_SetMenuItems( void )
{
    int				i;
    int				maxlen;
    char			modelskin[64];
    char*			buffptr;
    char*			pdest;

    // name
    Cvar_VariableStringBuffer( "name", s_playermodel.playername.string, 16 );
    Q_CleanStr( s_playermodel.playername.string );

    // model
    Cvar_VariableStringBuffer( "model", s_playermodel.modelskin, 64 );

    // find model in our list
    for (i=0; i<s_playermodel.nummodels; i++)
    {
        // strip icon_
        buffptr  = s_playermodel.modelnames[i] + strlen("models/players/");
        pdest    = strstr(buffptr,"icon_");
        if (pdest)
        {
            Q_strncpyz(modelskin,buffptr,pdest-buffptr+1);
            strcat(modelskin,pdest + 5);
        }
        else
            continue;

        if (!Q_stricmp( s_playermodel.modelskin, modelskin ))
        {
            // found pic, set selection here
            s_playermodel.selectedmodel = i;
            s_playermodel.modelpage     = i/MAX_MODELSPERPAGE;

            // seperate the model name
            maxlen = pdest-buffptr;
            if (maxlen > 16)
                maxlen = 16;
            Q_strncpyz( s_playermodel.modelname.string, buffptr, maxlen );
            Q_strupr( s_playermodel.modelname.string );

            // seperate the skin name
            maxlen = strlen(pdest+5)+1;
            if (maxlen > 16)
                maxlen = 16;
            Q_strncpyz( s_playermodel.skinname.string, pdest+5, maxlen );
            Q_strupr( s_playermodel.skinname.string );
            break;
        }
    }
}

/*
=================
PlayerModel_MenuInit
=================
*/
static void PlayerModel_MenuInit( void )
{
    int			i;
    int			j;
    int			k;
    int			x;
    int			y;
    static char	playername[32];
    static char	modelname[32];
    static char	skinname[32];

    // zero set all our globals
    memset( &s_playermodel, 0 ,sizeof(playermodel_t) );

    PlayerModel_Cache();

    s_playermodel.menu.key        = PlayerModel_MenuKey;
    s_playermodel.menu.wrapAround = qtrue;
    s_playermodel.menu.fullscreen = qtrue;

    s_playermodel.banner.generic.type  = MTYPE_BTEXT;
    s_playermodel.banner.generic.x     = 320;
    s_playermodel.banner.generic.y     = 16;
    s_playermodel.banner.string        = "PLAYER MODEL";
    s_playermodel.banner.color         = color_white;
    s_playermodel.banner.style         = UI_CENTER;

    s_playermodel.framel.generic.type  = MTYPE_BITMAP;
    s_playermodel.framel.generic.name  = MODEL_FRAMEL;
    s_playermodel.framel.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE;
    s_playermodel.framel.generic.x     = 0;
    s_playermodel.framel.generic.y     = 78;
    s_playermodel.framel.width         = 256;
    s_playermodel.framel.height        = 329;

    s_playermodel.framer.generic.type  = MTYPE_BITMAP;
    s_playermodel.framer.generic.name  = MODEL_FRAMER;
    s_playermodel.framer.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE;
    s_playermodel.framer.generic.x     = 376;
    s_playermodel.framer.generic.y     = 76;
    s_playermodel.framer.width         = 256;
    s_playermodel.framer.height        = 334;

    s_playermodel.ports.generic.type  = MTYPE_BITMAP;
    s_playermodel.ports.generic.name  = MODEL_PORTS;
    s_playermodel.ports.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE;
    s_playermodel.ports.generic.x     = 50;
    s_playermodel.ports.generic.y     = 59;
    s_playermodel.ports.width         = 274;
    s_playermodel.ports.height        = 274;

    y =	59;
    for (i=0,k=0; i<PLAYERGRID_ROWS; i++)
    {
        x =	50;
        for (j=0; j<PLAYERGRID_COLS; j++,k++)
        {
            s_playermodel.pics[k].generic.type	   = MTYPE_BITMAP;
            s_playermodel.pics[k].generic.flags    = QMF_LEFT_JUSTIFY|QMF_INACTIVE;
            s_playermodel.pics[k].generic.x		   = x;
            s_playermodel.pics[k].generic.y		   = y;
            s_playermodel.pics[k].width  		   = 64;
            s_playermodel.pics[k].height  		   = 64;
            s_playermodel.pics[k].focuspic         = MODEL_SELECTED;
            s_playermodel.pics[k].focuscolor       = colorRed;

            s_playermodel.picbuttons[k].generic.type	 = MTYPE_BITMAP;
            s_playermodel.picbuttons[k].generic.flags    = QMF_LEFT_JUSTIFY|QMF_NODEFAULTINIT|QMF_PULSEIFFOCUS;
            s_playermodel.picbuttons[k].generic.id	     = ID_PLAYERPIC0+k;
            s_playermodel.picbuttons[k].generic.callback = PlayerModel_PicEvent;
            s_playermodel.picbuttons[k].generic.x    	 = x - 16;
            s_playermodel.picbuttons[k].generic.y		 = y - 16;
            s_playermodel.picbuttons[k].generic.left	 = x;
            s_playermodel.picbuttons[k].generic.top		 = y;
            s_playermodel.picbuttons[k].generic.right	 = x + 64;
            s_playermodel.picbuttons[k].generic.bottom   = y + 64;
            s_playermodel.picbuttons[k].width  		     = 128;
            s_playermodel.picbuttons[k].height  		 = 128;
            s_playermodel.picbuttons[k].focuspic  		 = MODEL_SELECT;
            s_playermodel.picbuttons[k].focuscolor  	 = colorRed;

            x += 64+6;
        }
        y += 64+6;
    }

    s_playermodel.playername.generic.type  = MTYPE_PTEXT;
    s_playermodel.playername.generic.flags = QMF_CENTER_JUSTIFY|QMF_INACTIVE;
    s_playermodel.playername.generic.x	   = 320;
    s_playermodel.playername.generic.y	   = 440;
    s_playermodel.playername.string	       = playername;
    s_playermodel.playername.style		   = UI_CENTER;
    s_playermodel.playername.color         = text_color_normal;

    s_playermodel.modelname.generic.type  = MTYPE_PTEXT;
    s_playermodel.modelname.generic.flags = QMF_CENTER_JUSTIFY|QMF_INACTIVE;
    s_playermodel.modelname.generic.x	  = 497;
    s_playermodel.modelname.generic.y	  = 54;
    s_playermodel.modelname.string	      = modelname;
    s_playermodel.modelname.style		  = UI_CENTER;
    s_playermodel.modelname.color         = text_color_normal;

    s_playermodel.skinname.generic.type   = MTYPE_PTEXT;
    s_playermodel.skinname.generic.flags  = QMF_CENTER_JUSTIFY|QMF_INACTIVE;
    s_playermodel.skinname.generic.x	  = 497;
    s_playermodel.skinname.generic.y	  = 394;
    s_playermodel.skinname.string	      = skinname;
    s_playermodel.skinname.style		  = UI_CENTER;
    s_playermodel.skinname.color          = text_color_normal;

    s_playermodel.player.generic.type      = MTYPE_BITMAP;
    s_playermodel.player.generic.flags     = QMF_INACTIVE;
    s_playermodel.player.generic.ownerdraw = PlayerModel_DrawPlayer;
    s_playermodel.player.generic.x	       = 400;
    s_playermodel.player.generic.y	       = -40;
    s_playermodel.player.width	           = 32*10;
    s_playermodel.player.height            = 56*10;

    s_playermodel.arrows.generic.type		= MTYPE_BITMAP;
    s_playermodel.arrows.generic.name		= MODEL_ARROWS;
    s_playermodel.arrows.generic.flags		= QMF_INACTIVE;
    s_playermodel.arrows.generic.x			= 125;
    s_playermodel.arrows.generic.y			= 340;
    s_playermodel.arrows.width				= 128;
    s_playermodel.arrows.height				= 32;

    s_playermodel.left.generic.type			= MTYPE_BITMAP;
    s_playermodel.left.generic.flags		= QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS;
    s_playermodel.left.generic.callback		= PlayerModel_MenuEvent;
    s_playermodel.left.generic.id			= ID_PREVPAGE;
    s_playermodel.left.generic.x			= 125;
    s_playermodel.left.generic.y			= 340;
    s_playermodel.left.width  				= 64;
    s_playermodel.left.height  				= 32;
    s_playermodel.left.focuspic				= MODEL_ARROWSL;

    s_playermodel.right.generic.type	    = MTYPE_BITMAP;
    s_playermodel.right.generic.flags		= QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS;
    s_playermodel.right.generic.callback	= PlayerModel_MenuEvent;
    s_playermodel.right.generic.id			= ID_NEXTPAGE;
    s_playermodel.right.generic.x			= 125+61;
    s_playermodel.right.generic.y			= 340;
    s_playermodel.right.width  				= 64;
    s_playermodel.right.height  		    = 32;
    s_playermodel.right.focuspic			= MODEL_ARROWSR;

    s_playermodel.back.generic.type	    = MTYPE_BITMAP;
    s_playermodel.back.generic.name     = MODEL_BACK0;
    s_playermodel.back.generic.flags    = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS;
    s_playermodel.back.generic.callback = PlayerModel_MenuEvent;
    s_playermodel.back.generic.id	    = ID_BACK;
    s_playermodel.back.generic.x		= 0;
    s_playermodel.back.generic.y		= 480-64;
    s_playermodel.back.width  		    = 128;
    s_playermodel.back.height  		    = 64;
    s_playermodel.back.focuspic         = MODEL_BACK1;

    Menu_AddItem( &s_playermodel.menu,	&s_playermodel.banner );
    Menu_AddItem( &s_playermodel.menu,	&s_playermodel.framel );
    Menu_AddItem( &s_playermodel.menu,	&s_playermodel.framer );
    Menu_AddItem( &s_playermodel.menu,	&s_playermodel.ports );
    Menu_AddItem( &s_playermodel.menu,	&s_playermodel.playername );
    Menu_AddItem( &s_playermodel.menu,	&s_playermodel.modelname );
    Menu_AddItem( &s_playermodel.menu,	&s_playermodel.skinname );

    for (i=0; i<MAX_MODELSPERPAGE; i++)
    {
        Menu_AddItem( &s_playermodel.menu,	&s_playermodel.pics[i] );
        Menu_AddItem( &s_playermodel.menu,	&s_playermodel.picbuttons[i] );
    }

    Menu_AddItem( &s_playermodel.menu,	&s_playermodel.player );
    Menu_AddItem( &s_playermodel.menu,	&s_playermodel.arrows );
    Menu_AddItem( &s_playermodel.menu,	&s_playermodel.left );
    Menu_AddItem( &s_playermodel.menu,	&s_playermodel.right );
    Menu_AddItem( &s_playermodel.menu,	&s_playermodel.back );

    // find all available models
//	PlayerModel_BuildList();

    // set initial states
    PlayerModel_SetMenuItems();

    // update user interface
    PlayerModel_UpdateGrid();
    PlayerModel_UpdateModel();
}

/*
=================
PlayerModel_Cache
=================
*/
void PlayerModel_Cache( void )
{
    int	i;

    for( i = 0; playermodel_artlist[i]; i++ )
    {
        RE_RegisterShaderNoMip( playermodel_artlist[i] );
    }

    PlayerModel_BuildList();
    for( i = 0; i < s_playermodel.nummodels; i++ )
    {
        RE_RegisterShaderNoMip( s_playermodel.modelnames[i] );
    }
}

void UI_PlayerModelMenu(void)
{
    PlayerModel_MenuInit();

    UI_PushMenu( &s_playermodel.menu );

    Menu_SetCursorToItem( &s_playermodel.menu, &s_playermodel.pics[s_playermodel.selectedmodel % MAX_MODELSPERPAGE] );
}


